package com.springboot.cloud.demos.feign.weixin;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.springboot.cloud.common.web.entity.constant.WeixinConstant;
import com.springboot.cloud.common.web.redis.CacheDuration;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Component

public class WeixinAccessTokenProvider {
    private Logger logger = LoggerFactory.getLogger(this.getClass());


    private  final String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
            + WeixinConstant.WEIXIN_MINA_APP_ID + "&secret=" + WeixinConstant.WEIXIN_MINA_SECRET;
    @CacheDuration(7000)
    @Cacheable(value = "wxAccessToken", key = "'wxAccessToken'", unless = "#result == null")
    public String accessToken() {
        Request request = new Request.Builder().get().url(GET_ACCESS_TOKEN_URL).build();
        try {
            Response response = new OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS)
                    .readTimeout(30, TimeUnit.SECONDS).writeTimeout(30, TimeUnit.SECONDS).build().newCall(request)
                    .execute();

            if (response.isSuccessful()) {
                JSONObject jsonObject = JSON.parseObject(response.body().string());
                Integer errorCode = jsonObject.getInteger("errcode");

                if (errorCode == null || errorCode.intValue() == 0) {
                    return jsonObject.getString("access_token");
                }
            }

            logger.error("get weixin access token fail, status code = {}, response body = {}", response.code(),
                    response.body().string());
        } catch (IOException e) {
            logger.error("get weixin access token error", e);
        }

        return null;
    }
}
